package com.emar.adx.yiqifa.thread;

import com.emar.adx.yiqifa.util.HikariCPPoolUtil;
import com.emar.adx.yiqifa.util.RandomUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

/**
 * Created by xiaoliang
 * 2016.12.05 10:33
 *
 * @Version 1.0
 */
public class OracleDBThread implements Runnable {
    private static final Logger logger = LoggerFactory.getLogger(OracleDBThread.class);

    private Connection conn = null;
    private PreparedStatement pre = null;
    private Map<Integer, String> tableMap = new HashMap<Integer, String>();
    private Properties properties = null;

    private int total =100;
    private int index = 100;

    public OracleDBThread(Map<Integer, String> tableMap, int index) {
        this.tableMap = tableMap;
        this.index = index;
    }

    public void setTotal(int total) {
        this.total = total;
    }

    @Override
    public void run() {
        int i = 0;
        while(i<total){
            singleInsert();
            logger.info(Thread.currentThread().getId() + " --> singleInsert insert end , execute i = "+i);
            i ++;
        }
    }

    /**
     * 随机获取tablename
     *
     * @return
     */
    private String getTableName() {
        int i = RandomUtil.random(0, index);
        return tableMap.get(i);
    }


    private String parseType(String oracleType) {
        switch (oracleType){
            case "VARCHAR2": return "String";
            case "VARCHAR" : return "String";
            default: return "";
        }
    }

    public void singleInsert() {
        String tableName = this.getTableName();
        String columeSql = "select column_name,data_type,data_length from user_tab_columns where table_name= ? ";

        logger.info("start single insert...");
        try {
            conn = HikariCPPoolUtil.getConnection();
            pre = conn.prepareStatement(columeSql);
            pre.setString(1, tableName);

            Map<String, String> dataTypes = new HashMap<>();

            ResultSet res = pre.executeQuery();
            StringBuilder colums = new StringBuilder(500);
            StringBuilder params = new StringBuilder(500);
            int paramsNum = 0;
            List<String> datas = new ArrayList<>();

            if (res != null) {
                while (res.next()) {
                    String columName = res.getString(1);
                    String columType = res.getString(2);
                    int dataLen = res.getInt(3);
                    int minLen = 40;

                    String type = this.parseType(columType);
                    if (StringUtils.isNotBlank(type)) {
                        dataTypes.put(columName, type);
                        colums.append(",").append(columName);
                        params.append(",").append("?");
                        if(dataLen<minLen){
                            minLen = dataLen;
                        }
                        datas.add(RandomUtil.getRandomString(minLen));
                        paramsNum++;
                    }
                }
                res.close();
            }

            StringBuilder sb = new StringBuilder(1000);
            sb.append("insert into ").append(tableName).append("(")
                    .append(colums.toString().replaceFirst(",", ""))
                    .append(") values (")
                    .append(params.toString().replaceFirst(",", ""))
                    .append(")");

            if (paramsNum > 0) {
                pre = conn.prepareStatement(sb.toString());
                logger.info("insert sql = " + sb.toString());
                for (int i = 1; i <= paramsNum; i++) {
                    pre.setString(i, datas.get(i - 1));
                }
                pre.executeUpdate();
            }

        } catch (SQLException e) {
            logger.error("error : ", e);
        }finally {
            HikariCPPoolUtil.closePreparedStatement(pre);
            HikariCPPoolUtil.closeConnection(conn);
        }
        logger.info(Thread.currentThread().getId() + " --> single insert end ...");
    }


}
